package com.k.fw.dfs.minio;

import com.google.common.collect.Maps;
import io.minio.BucketExistsArgs;
import io.minio.DownloadObjectArgs;
import io.minio.GetBucketEncryptionArgs;
import io.minio.GetBucketLifecycleArgs;
import io.minio.GetBucketNotificationArgs;
import io.minio.GetBucketPolicyArgs;
import io.minio.GetBucketReplicationArgs;
import io.minio.GetBucketTagsArgs;
import io.minio.GetBucketVersioningArgs;
import io.minio.GetObjectArgs;
import io.minio.GetObjectLockConfigurationArgs;
import io.minio.ListBucketsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.ServerSideEncryptionCustomerKey;
import io.minio.messages.Bucket;
import io.minio.messages.LifecycleConfiguration;
import io.minio.messages.NotificationConfiguration;
import io.minio.messages.ObjectLockConfiguration;
import io.minio.messages.ReplicationConfiguration;
import io.minio.messages.SseConfiguration;
import io.minio.messages.Tags;
import io.minio.messages.VersioningConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import javax.crypto.spec.SecretKeySpec;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

//https://blog.csdn.net/qq_22885233/article/details/122829045
@Slf4j
public class MinioDemo {
    String bucket = "123";
    String objName = "baidu.png";
    String bucketNew = "123new";
    String bucketSecret = "secret";

    public void test1() {
        MinioClient minioClient =
                MinioClient.builder()
                        .endpoint("https://play.min.io:9000")
                        .credentials("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG")
                        .region("eu-east-1")
                        //.httpClient(customHttpClient)
                        .build();
    }

    public MinioClient buildClient() {
        //构造方法 minio客户端
        MinioClient minioClient = MinioClient.builder()
                .endpoint("http://minio:9100/")
                .credentials("adminminio", "adminminio")
                .build();
        return minioClient;
    }

    @Test
    public void bucketExist() throws Exception {
        MinioClient client = buildClient();
        boolean found =
                client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
        if (found) {
            log.info("{} exist", bucket);
        } else {
            log.info("{} no exist", bucket);
        }
    }

    @Test
    public void makeExist() throws Exception {
        MinioClient client = buildClient();
        client.makeBucket(MakeBucketArgs.builder().bucket(bucketNew).build());
        boolean found =
                client.bucketExists(BucketExistsArgs.builder().bucket(bucketNew).build());
        if (found) {
            log.info("{} exist", bucket);
        } else {
            log.info("{} no exist", bucket);
        }
    }

    @Test
    public void listbucket() throws Exception {
        MinioClient client = buildClient();
        // 列出所有桶
        List<Bucket> bucketList = client.listBuckets();
        for (Bucket bucket : bucketList) {
            log.info(bucket.creationDate() + ", " + bucket.name());
        }

//列出所有桶，包括桶的信息。
        List<Bucket> bucketList1 = client.listBuckets(ListBucketsArgs.builder().extraHeaders(Maps.newHashMap()).build());
        for (Bucket bucket : bucketList) {
            log.info(bucket.creationDate() + ", " + bucket.name());
        }


//获取加密通getBucketEncryption
        SseConfiguration config =
                client.getBucketEncryption(
                        GetBucketEncryptionArgs.builder().bucket(bucket).build());

//获取生命周期桶getBucketLifecycle
        LifecycleConfiguration config1 =
                client.getBucketLifecycle(
                        GetBucketLifecycleArgs.builder().bucket(bucket).build());
        log.info("Lifecycle configuration:{} ", config1);

//获取通知桶信息getBucketNotification
        NotificationConfiguration config2 =
                client.getBucketNotification(
                        GetBucketNotificationArgs.builder().bucket(bucket).build());
//获取策略桶信息getBucketPolicy
        String config3 =
                client.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucket).build());
//获取复制桶getBucketReplication
        ReplicationConfiguration config4 =
                client.getBucketReplication(
                        GetBucketReplicationArgs.builder().bucket(bucket).build());
//获取标签桶getBucketTags
        Tags tags = client.getBucketTags(GetBucketTagsArgs.builder().bucket(bucket).build());
        // 获取版本桶getBucketVersioning
        VersioningConfiguration config5 =
                client.getBucketVersioning(
                        GetBucketVersioningArgs.builder().bucket(bucket).build());
//获取对象锁的桶信息getObjectLockConfiguration
        ObjectLockConfiguration config6 =
                client.getObjectLockConfiguration(
                        GetObjectLockConfigurationArgs.builder().bucket(bucket).build());
        log.info("Mode :{} ", config6.mode());
        log.info("Duration :{} ", (config6.duration().duration() + "" + config6.duration().unit()));
    }

    @Test
    public void readObject() throws Exception {
        MinioClient client = buildClient();
//获得对象流
        try (InputStream stream = client.getObject(
                GetObjectArgs.builder()
                        .bucket(bucket)
                        .object(objName)
                        .build())) {
            // Read data from stream
        }
// 获得对象流 。设置偏移量 seek用法相同
        try (InputStream stream = client.getObject(
                GetObjectArgs.builder()
                        .bucket(bucket)
                        .object(objName)
                        .offset(1024L)
                        .build())) {
            // Read data from stream
        }
// 获取读取流长度
        try (InputStream stream = client.getObject(
                GetObjectArgs.builder()
                        .bucket(bucket)
                        .object(objName)
                        .offset(1024L)
                        .length(4096L)
                        .build())) {
            // Read data from stream
        }

        ServerSideEncryptionCustomerKey srcSsec =
                new ServerSideEncryptionCustomerKey(
                        new SecretKeySpec(
                                bucketSecret.getBytes(StandardCharsets.UTF_8), "AES"));
// 获取读取 sse-c 加密文件
        try (InputStream stream = client.getObject(
                GetObjectArgs.builder()
                        .bucket(bucket)
                        .object(objName)
                        .ssec(srcSsec)
                        .build())) {
            // Read data from stream
        }
// 获取读取 sse-c 加密文件  带偏移量 带长度
        try (InputStream stream = client.getObject(
                GetObjectArgs.builder()
                        .bucket(bucket)
                        .object(objName)
                        .offset(1024L)
                        .length(4096L)
                        .ssec(srcSsec)
                        .build())) {
            // Read data from stream
        }
    }

    @Test
    public void down() throws Exception {
        MinioClient client = buildClient();
        //下载文件到输出流my-filename
        client.downloadObject(
                DownloadObjectArgs.builder()
                        .bucket(bucket)
                        .object(objName)
                        .filename("123.png")
                        .build());
        log.info("down {}:{}", bucket, objName);

    }

    @Test
    public void downWithSecret() throws Exception {
        MinioClient client = buildClient();


//下载带有密码的文件
        ServerSideEncryptionCustomerKey srcSsec =
                new ServerSideEncryptionCustomerKey(
                        new SecretKeySpec(
                                bucketSecret.getBytes(StandardCharsets.UTF_8), "AES"));
        client.downloadObject(
                DownloadObjectArgs.builder()
                        .bucket(bucket)
                        .object(objName)
                        .ssec(srcSsec)
                        .filename(objName)
                        .build());
    }
}
